/**
 * 
 */
package com.kingcore.director.main;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.sql.Connection;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JOptionPane;

import wzw.util.DbUtils;
import wzw.util.FileUtils;

import com.kingcore.director.core.util.DirectorComponentUtils;
import com.kingcore.framework.context.DataSourceManager;


/**
 * 
 *  通用系统更新器。
 *   更新管理的目录：  本处理放在数据库配置初始之后、数据库操作之前。
 *    appHome/update/sql/*.sql       //保存所有要更新的sql文件
 *    appHome/update/tmp/update.log  //更新日志文件
 *    
 * @author Zeven
 */
public class SystemUpdater {

	private static SystemUpdater instance = null;
	
	private SystemUpdater(){
		super();
	}
	
	public static SystemUpdater getInstance(){
		if (instance==null) {
			instance = new SystemUpdater();
		}
		return instance;
	}
	
    public int updateDatabase(DataSourceManager dsm, String appHome) {
        //check parent folder
    	String appUpdateHome = appHome+File.separator+"update";
        File sqlFolder = new File( appUpdateHome+File.separator+"sql");
        if (!sqlFolder.exists()) {
            sqlFolder.mkdirs();
            return 0;
        }
        FileInputStream fis = null;
        InputStreamReader isr = null;
        BufferedReader br = null;
        Connection conn = null;
        Statement stmt = null;
        List<File> delFiles = null; 
        try {
            //loop all .sql files
            File[] sqlFiles = sqlFolder.listFiles();
            if (sqlFiles.length<1) {
				return 0;
			}
            delFiles = new ArrayList<File>(); 
        	conn = dsm.getConnection();
            conn.setAutoCommit(false);
            stmt = conn.createStatement();
            for (File file : sqlFiles) {
                if (file.getName()==null || !file.getName().toLowerCase().endsWith(".sql")) {
                    continue;
                }
                // deal each sql file, update database and record logs
                fis=new FileInputStream(file);
                isr=new InputStreamReader(fis, "GBK");
                br = new BufferedReader(isr);
                //简写如下
                String line="";
                StringBuffer sb_sql = new StringBuffer();
                while ((line=br.readLine())!=null) {
                    if (line.trim().toLowerCase().indexOf("commit")==0) { //提交事务
                        try {
                            stmt.executeBatch();
                            conn.commit();
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    } else {
	                    sb_sql.append(line);
	                    if (line.trim().endsWith(";")) {  //添加sql
	                        stmt.addBatch(sb_sql.toString());
	                        sb_sql.delete(0, sb_sql.length());
	                    }
                    }
                }
                //删除文件，记录日志
                delFiles.add(file);  //file.delete();
                this.writeUpdateLog(appUpdateHome+File.separator+"tmp"+File.separator+"update.log"
                                    ,"update "+file.getName()+"完成！");
            }
           
        } catch (Exception e) {
            e.printStackTrace();
            DbUtils.rollbackQuietly(conn); //最后必须回滚一次，避免死锁
        } finally{
            DbUtils.commitQuietly(conn); //最后必须提交一次，避免死锁

            if (conn!=null) {
	            try {
	         	    conn.setAutoCommit(true);
	 			} catch (Exception e) {
	 				e.printStackTrace();
	 			}
            }
	 			
            DbUtils.closeQuietly(conn, stmt, null);

            if (br!=null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (isr!=null) {
                try {
                    isr.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fis!=null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            
            if (delFiles!=null && delFiles.size()>0) { //tips
                // 移动升级sql文件到其他目录保留
                for(File file : delFiles){
                	FileUtils.move(file, appUpdateHome+File.separator+"tmp");
                	try {
                    	file.delete();
    				} catch (Exception e) {
    					e.printStackTrace();
    				}
                }
                
            	DirectorComponentUtils.sleepQuietly(3000); //建成表后需要等待个几秒,然后再往里面悼数据,就不会报错了!
                JOptionPane.showMessageDialog(null, "System Update Successfully!");
            	DirectorComponentUtils.sleepQuietly(2000);
                return 1;
			}
        }
        return 0;
       
    }
   

    public void writeUpdateLog(String logFile, String content) throws IOException {

        FileOutputStream fos = null;
        OutputStreamWriter osw = null;
        BufferedWriter  bw = null;
        //写入中文字符时解决中文乱码问题
        try {
        	File logF = new File(logFile);
        	if (!logF.exists()) {
				logF.createNewFile();
				logF = new File(logFile); // 重新实例化
			}
            fos=new FileOutputStream(logF, true);  //true表示append
            osw=new OutputStreamWriter(fos, "GBK");
             bw=new BufferedWriter(osw);
            //简写如下：
            //BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
            //        new FileOutputStream(new File("E:/phsftp/evdokey/evdokey_201103221556.txt")), "UTF-8"));
            bw.write("\n" + content);  //append  write.
            
        } catch (Exception e) {
            e.printStackTrace();
           
        } finally{
            if (bw!=null) {
                try {
                    bw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (osw!=null) {
                try {
                    osw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fos!=null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub

	}
}